require 'erb'
require 'components/CFM/base'
require 'components/CFM/vlan_tag'

class CommonCFMHeader

  attr_accessor :message
  
  def initialize(base, md_level=0, opcode=0, flags=0, tlv_offset=0)
    @base = base
    @md_level = md_level
    @opcode = opcode
    @flags = flags
    @tlv_offset = tlv_offset

    @vlan_tag = VlanTag.new(@base, @base.vlan_identifier).message
    # if using vlan_tag, insert the following into the first line of the template below
    # <%= @vlan_tag %>

    # TODO: should the 0x8902 struct fo in the CCM message only, before the common header?
    
    template = '
         struct [
            0he640
            # ieee8021ah_etype|Type: IEEE 802.1ag Connectivity Fault Management (CFM) protocol (0x8902)
            0x8902:16
          ]
          header_<%= @base.step %> = struct [
            # MD Level|MD Level
            <%= @md_level %>:3
            # Version, always 0|Version
            0:5
            # OpCode (0:255)|Opcode
            <%= @opcode %>:8
            # Flags|Flags
            <%= @flags %>:8
            # First TLV Offset|First TLV Offset
            <%= @tlv_offset %>:8
           ]'

    erb = ERB.new(template, 0, '%<>')
    @message = erb.result(binding)
    
  end

end

=begin
  Table 21-3—Common CFM Header format
                               Octet
  MD Level                       1 (high-order 3 bits)
  Version                        1 (low-order 5 bits)
  OpCode                         2
  Flags                          3
  First TLV Offset               4
  Varies with value of OpCode    5
  End TLV (0)                    First TLV Offset + 5

Table 21-4—OpCode Field range assignments
   CFM PDU or organization           OpCode range
   Reserved for IEEE 802.1                0
   Continuity Check Message (CCM)         1
   Loopback Reply (LBR)                   2
   Loopback Message (LBM)                 3
   Linktrace Reply (LTR)                  4
   Linktrace Message (LTM)                5
   Reserved for IEEE 802.1              6 – 31
   Defined by ITU-T Y.1731             32 – 63
   Reserved for IEEE 802.1.            64 – 255

21.4.5 First TLV Offset

(1 octet) The offset, starting from the first octet following the First TLV Offset field,
up to the first TLV in the CFM PDU. The value of the First TLV Offset field shall be
transmitted as indicated in the specification  for each of the OpCode field values,
as follows (21.6.2, 21.7.2, 21.8.2, and 21.9.2).

 TLV Format   Octet
  Type          1
  Length      2 – 3
 (Value)        4

 1.5.1.1 Type

(1 octet) Required. If 0, no Length or Value fields follow. If not 0, at least the Length field follows the Type
field. The Type field is encoded as shown in Table 21-6.

21.5.1.2 Length

(2 octets) Required if the Type field is not 0. Not present if the Type field is 0. The 16 bits of the Length field
indicate the size, in octets, of the Value field. 0 in the Length field indicates that there is no Value field.

21.5.1.3 Value

(Length specified by the Length field) Optional. Not present if the Type field is 0 or if Length field is 0.

Table 21-6—Type Field values
 TLV or organization         Type field
  End TLV                        0
  Sender ID TLV                  1
  Port Status TLV                2
  Data TLV                       3
  Interface Status TLV           4
  Reply Ingress TLV              5
  Reply Egress TLV               6
  LTM Egress Identifier TLV      7
  LTR Egress Identifier TLV      8
  Reserved for IEEE 802.1      9 – 30
  Organization-Specific TLV     31
  Defined by ITU-T Y.1731     32 – 63
  Reserved for IEEE 802.1     64 – 255

Table 21-7—Organization-Specific TLV format
                      Octet
  Type = 31            1
  Length              2 – 3
  OUI                 4 – 6
  Sub-Type              7
  Value (optional)    8 – (Length + 3)

=end